package app

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"shop-admin/config"
	"shop-admin/startup"
	"shop-common/engine"
	"shop-common/library/variables"
	"strconv"
	"time"
)

func RunApplication(application *engine.WEBApplication) {
	if application.Name == "" {
		log.Fatalf("Application name can't not be empty")
	}
	flag.Parse()
	err := runApp(application)
	if err != nil {
		log.Fatalf("App.RunListenerApplication err: %v", err)
	}
}

func runApp(webApp *engine.WEBApplication) error {
	if webApp.SetupApp != nil {
		err := webApp.SetupApp(config.Config.Env)
		if err != nil {
			return fmt.Errorf("App.LoadConfig err: %v", err)
		}
	}

	if err := initApplication(webApp.Application.Name); err != nil {
		return err
	}

	if webApp.SetupVars != nil {
		err := webApp.SetupVars()
		if err != nil {
			return fmt.Errorf("App.SetupVars err: %v", err)
		}
	}

	if webApp.CreateTables != nil {
		err := webApp.CreateTables()
		if err != nil {
			return fmt.Errorf("App.CreateTables err: %v", err)
		}
	}

	if webApp.ServiceImpl != nil {
		if err := webApp.ServiceImpl(variables.GormDB()); err != nil {
			return err
		}
	}

	var addr string
	if config.Config.Server.Port != 0 {
		addr = "0.0.0.0:" + strconv.Itoa(config.Config.Server.Port)
	}

	httpSrvHandler := &http.Server{
		Addr:         addr,
		Handler:      webApp.RegisterHttpRoute(),
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 30 * time.Second,
	}
	go func() {
		// 定时任务
		if webApp.CronScheduler != nil {
			err := startup.StartKnownScheduler(webApp.CronScheduler())
			if err != nil {
				log.Fatalf("cron known task fail: %s\n", err)
			}
		}

		// 监听请求
		if err := httpSrvHandler.ListenAndServe(); err != nil {
			log.Fatalf("%s run listen: %s\n", webApp.Name, err)
		}
	}()

	engine.Stop(httpSrvHandler, variables.GormDB(), variables.RedisConn)
	return nil
}
